package com.clp.protocol.modbus_tcp.mb_frame.mb_body;

import com.clp.protocol.modbus_tcp.definition.FuncCode;
import com.clp.protocol.modbus_tcp.mb_frame.mb_body.mb_data.ReqMbData;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.Objects;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ReqMbBody implements MbBody {

    /**
     * 单元标识符 / 从站地址 / 设备地址
     */
    private int addr;
    /**
     * 功能码类型
     */
    private FuncCode funcCode;
    private ReqMbData data;

    @Override
    public ReqMbBody initBy(ByteBuf buf) {
        this.addr = buf.readByte() & 0xFF;
        this.funcCode = FuncCode.gain((byte) (buf.readByte() & 0x7F));
        this.data = funcCode.newInvalidReqMbData().initBy(buf);
        return this;
    }

    @Override
    public boolean isValid() {
        if (addr < 0 || addr > 0xFF) return false;
        if (funcCode == null) return false;
        return data != null && data.isValid();
    }

    @Override
    public void writeTo(ByteBuf buf) {
        // 单元标识符 / 从站地址
        buf.writeByte(addr);
        buf.writeByte(funcCode.getVal());
        data.writeTo(buf);
    }

    @Override
    public String toString() {
        return "从站地址：" + addr + ", 功能码：" + funcCode + "(" + funcCode.getDesc() + "), " + data;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ReqMbBody reqMbBody = (ReqMbBody) o;
        return addr == reqMbBody.addr && funcCode == reqMbBody.funcCode && Objects.equals(data, reqMbBody.data);
    }

    @Override
    public int hashCode() {
        return Objects.hash(addr, funcCode, data);
    }
}
